#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

typedef enum {
	E_DOWN_PARA_HEAD = 1,
	E_DOWN_PARA_POST = 2,
	E_DOWN_PARA_AGENT = 3,
	E_DOWN_PARA_POST_DATA = 4,
	E_DOWN_PARA_NULL = 0
} down_para_e;

struct curldown_para_t {
	const char *name;
	down_para_e val;
};

// return -1 for error, 0 for end, 1 for success
int parse_one( down_para_e &para, const char *fmt, int &off_set )
{
	const static curldown_para_t paras[] = {
		{ "head", E_DOWN_PARA_HEAD },
		{ "post_data", E_DOWN_PARA_POST_DATA },
		{ "POST", E_DOWN_PARA_POST },
		{ "agent", E_DOWN_PARA_AGENT },
		{ NULL, E_DOWN_PARA_NULL }
	};

	const char *begin = fmt + off_set;

	if( '\0' == *begin )
		return 0;
	size_t n = strcspn( begin, "%" );
	if( 0 == n )
		return -1;

	int i = 0;
	for(; paras[i].name != NULL; i++ ) {
		if( strncasecmp( begin, paras[i].name, n ) == 0 && strlen( paras[i].name ) == n ) {
			para = paras[i].val;
			off_set += n + (*(begin + n) == '%' ? 1 : 0);
			break;
		}
	}

	if( paras[i].name == NULL )
		return -1;
	else
		return 1;
}

int parse_var_opt( const char *fmt = NULL, ... )
{
	if( NULL == fmt )
		return 0;

	va_list ap;
	va_start( ap, fmt );

	down_para_e para = E_DOWN_PARA_NULL;
	int off_set = 0;
	int ret;
	while( true ) {
		ret = parse_one( para, fmt, off_set );
		if( ret < 0 ) {
			printf( "format error\n" );
			break;
		}

		if( 0 == ret ) {
			printf( "reach end\n" );
			break;
		}

		printf( "parse result: %d\n", para );
	}

	va_end( ap );

	return 0;
}

int main( int argc, char *argv[] )
{
	//parse_var_opt();
	if( argc <= 1 )
		parse_var_opt( "agent%head%pOst" );
	else
		parse_var_opt( argv[1] );
	return 0;
}
